<?php
namespace Ysgao\PhpWakeonlan;

class Wakeonlan {
   
   /**
    * 唤醒远程终端
    * @param $mac 被唤醒终端的MAC
    * @return bool
    */
   public static function wakeonlan($mac)
   {
       $mac_split = explode(':', $mac);
       $mac_split = array_map(function ($v) {
           return trim($v);
       }, $mac_split);

       $hw_addr = null;
       foreach ($mac_split as $split) {
           $hw_addr .= chr(hexdec($split)); // 十六进制转十进制，在转成单字节字符（不一定能打印）
       }

       $wol_msg = sprintf(
           '%s%s',
           str_repeat(chr(255), 6), // 6次‘ff’
           str_repeat($hw_addr, 16) // 16次mac字符
       );

       $socket_ip = '255.255.255.255'; // 广播
       $socket_port = 9; // 端口9为丢弃端口，discard（收到什么，丢弃什么）
       // 创建socket套接字
       $sock = socket_create(
           AF_INET, // ipv4
           SOCK_DGRAM, // 提供数据报文的支持
           SOL_UDP // 使用udp协议
       );
       if ($sock == false) {
           return false;
       }
       // 设置socket套接字
       $set_opt = socket_set_option(
           $sock,
           SOL_SOCKET, // 指定在socket协议级别设置
           SO_BROADCAST, // 是否支持传输广播消息
           true // 选项值
       );
       if ($set_opt == false) {
           socket_close($sock);
           return false;
       }
       // 发送数据包
       $sendto = socket_sendto(
           $sock,
           $wol_msg,
           strlen($wol_msg),
           0, // 应该是不设置标记的意思
           $socket_ip,
           $socket_port
       );

       socket_close($sock);
       if (!$sendto) {
           return false;
       }
       return true;
   }
   
}